package com.aaa.rsatest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.text.TextUtils;

import com.aaa.lib_java.RSAUtils;
import com.aaa.lib_java.java.Base64;
import com.aaa.lib_java.mdm.Encrypt;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

//        generateKeyPair();
//        rsaTest();

        loadKeyPair();
        rsaTest2();
    }

    public void loadKeyPair() {
        // 从文件加载秘钥对
        PublicKey publicKey = null;
        PrivateKey privateKey = null;
        SPUtils spUtils = SPUtils.getInstance(getApplicationContext());
        try {
            System.out.println("从私钥文件加载私钥 pkcs8_server.key");
            InputStream in = getResources().getAssets().open("pkcs8_server.key");
            privateKey = RSAUtils.loadPrivateKey(in);
            RSAUtils.printPrivateKeyInfo(privateKey);
            byte[] bytes = privateKey.getEncoded();
            String string = Base64.getEncoder().encodeToString(bytes);
            spUtils.setPrivateKey2(string);

            System.out.println("从公钥文件加载公钥 server_public.key");
            in = getResources().getAssets().open("server_public.key");
            publicKey = RSAUtils.loadPublicKey(in);
            RSAUtils.printPublicKeyInfo(publicKey);
            bytes = publicKey.getEncoded();
            System.out.println("bytes=" + Arrays.toString(bytes));
            string = Base64.getEncoder().encodeToString(bytes);
            spUtils.setPublicKey2(string);

            // 从文件加载公钥，得到字节数组，通过X509EncodedKeySpec再得到公钥，再得到字符数组
            try {
                PublicKey publicKey1 = RSAUtils.getPublicKey(bytes);
                bytes = publicKey1.getEncoded();
                System.out.println("bytes=" + Arrays.toString(bytes));
            } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
                e.printStackTrace();
            }

            System.out.println("从证书文件加载公钥 server.crt");
            in = getResources().getAssets().open("server.crt");
            // 获取X.509对象工厂
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            // 生成一个证书对象并使用从输入流 inStream 中读取的数据对它进行初始化。
            Certificate c = cf.generateCertificate(in);
            publicKey = c.getPublicKey();
            RSAUtils.printPublicKeyInfo(publicKey);
            bytes = publicKey.getEncoded();
            System.out.println("bytes=" + Arrays.toString(bytes));
            string = Base64.getEncoder().encodeToString(bytes);
            spUtils.setPublicKey3(string);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void rsaTest2() {
        SPUtils spUtils = SPUtils.getInstance(getApplicationContext());
        // 加解密
        String pwd = "010287";
        System.out.println("明文=" + pwd);

        String string = spUtils.getPrivateKey2();
        byte[] bytes = Base64.getDecoder().decode(string); //
        PrivateKey privateKey = null;
        try {
            privateKey = RSAUtils.getPrivateKey(bytes);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }

        string = spUtils.getPublicKey2();
        bytes = Base64.getDecoder().decode(string); //
        PublicKey publicKey = null;
        try {
            publicKey = RSAUtils.getPublicKey(bytes);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }

        System.out.println("******私钥加密，公钥解密，bytes2HexString传输******");
        bytes = RSAUtils.encryptDataPrivate(pwd.getBytes(), privateKey);
        System.out.println("加密=" + Arrays.toString(bytes));
        string = RSAUtils.bytes2HexString(bytes);
        System.out.println("加密并bytes2HexString=" + string + "---");
        bytes = RSAUtils.hexString2Bytes(string);
        bytes = RSAUtils.decryptDataPublic(bytes, publicKey);
        string = new String(bytes);
        System.out.println("解密=" + string);

        string = spUtils.getPublicKey3();
        bytes = Base64.getDecoder().decode(string); //
        try {
            publicKey = RSAUtils.getPublicKey(bytes);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }

        System.out.println("******私钥加密，公钥解密******java的base64传输******");
        bytes = RSAUtils.encryptDataPrivate(pwd.getBytes(), privateKey);
        System.out.println("加密=" + Arrays.toString(bytes));
        string = Base64.getEncoder().encodeToString(bytes);
        System.out.println("加密并java的base64=" + string + "---");
        bytes = Base64.getDecoder().decode(string);
        bytes = RSAUtils.decryptDataPublic(bytes, publicKey);
        string = new String(bytes);
        System.out.println("解密=" + string);
    }

    public void generateKeyPair() {
        // 生成秘钥对，并持久化
        SPUtils spUtils = SPUtils.getInstance(getApplicationContext());
        if (TextUtils.isEmpty(spUtils.getPrivateKey())) {
            KeyPair keyPair = RSAUtils.generateRSAKeyPair(2048);

            byte[] encoded = keyPair.getPrivate().getEncoded();
            String string = Arrays.toString(encoded);
            string = RSAUtils.bytes2HexString(encoded);
            spUtils.setPrivateKey(string);
            System.out.println("keyPair.getPrivate().getEncoded=" + string + "---");

            encoded = keyPair.getPublic().getEncoded();
            string = Arrays.toString(encoded);
            string = RSAUtils.bytes2HexString(encoded);
            spUtils.setPublicKey(string);
            System.out.println("keyPair.getPublic().getEncoded=" + string + "---");
        }
    }

    public void rsaTest() {
        SPUtils spUtils = SPUtils.getInstance(getApplicationContext());
        // 加解密
        String pwd = "010287";
        System.out.println("明文=" + pwd);

        String string = spUtils.getPrivateKey();
        byte[] bytes = RSAUtils.hexString2Bytes(string);
        PrivateKey privateKey = null;
        try {
            privateKey = RSAUtils.getPrivateKey(bytes);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }

        string = spUtils.getPublicKey();
        bytes = RSAUtils.hexString2Bytes(string);
        PublicKey publicKey = null;
        try {
            publicKey = RSAUtils.getPublicKey(bytes);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }

        System.out.println("******私钥加密，公钥解密，bytes2HexString传输******");
        bytes = RSAUtils.encryptDataPrivate(pwd.getBytes(), privateKey);
        System.out.println("加密=" + Arrays.toString(bytes));
        string = RSAUtils.bytes2HexString(bytes);
        String newString = string;
        System.out.println("加密并bytes2HexString=" + string + "---");
        bytes = RSAUtils.hexString2Bytes(string);
        byte[] newbytes = bytes;
        bytes = RSAUtils.decryptDataPublic(bytes, publicKey);
        string = new String(bytes);
        System.out.println("解密=" + string);

        // RSA算法生成秘钥对，android RSA私钥加密，RSA公钥解密 ok 但 java RSA公钥解密 BadPaddingException
        // RSA算法生成秘钥对，android RSA/ECB/PKCS1Padding私钥加密，RSA/ECB/PKCS1Padding公钥解密 ok 且 java RSA/ECB/PKCS1Padding公钥解密 也ok

        System.out.println("******私钥加密，公钥解密******Encrypt******");
        string = spUtils.getPublicKey();
        try {
            publicKey = Encrypt.loadPublicKey(string);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            System.out.println("Encrypt的hex2byte去解bytes2HexString");
            newbytes = Encrypt.hex2byte(newString);
            newbytes = Encrypt.decrypt((RSAPublicKey) publicKey, newbytes);
            string = new String(newbytes);
            System.out.println("解密=" + string);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
